﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Entity;
using IRepository;
using IService;
using Microsoft.Extensions.Logging; // 需引入日志依赖

namespace Service
{
    public class PurchaseOrderService : IPurchaseOrderService
    {
        private readonly IPurchaseOrderRepository _purchaseOrderRepo;
        private readonly ILogger<PurchaseOrderService> _logger; // 日志组件

        // 注入日志（依赖注入）
        public PurchaseOrderService(
            IPurchaseOrderRepository purchaseOrderRepo,
            ILogger<PurchaseOrderService> logger)
        {
            _purchaseOrderRepo = purchaseOrderRepo;
            _logger = logger;
        }

        /// <summary>
        /// 新增进货订单（含明细），事务保证主表和明细的一致性
        /// </summary>
        public async Task<bool> AddPurchaseOrderWithDetailsAsync(PurchaseOrderEntity order, List<WmsOrderDetails> details)
        {
            try
            {
                // 1. 增强参数校验（确保核心字段有效）
                ValidateOrderAndDetails(order, details);

                // 2. 自动填充服务端字段（避免前端传入无效值）
                FillServerSideFields(order, details);

                // 3. 开启事务（确保主表和明细同成功/同失败）
                using var transaction = _purchaseOrderRepo.BeginTransaction();
                try
                {
                    // 3.1 插入主表，获取自增ID
                    int purchaseId = await _purchaseOrderRepo.AddPurchaseOrderAsync(order, transaction);
                    _logger.LogInformation($"进货订单主表插入成功，ID：{purchaseId}");

                    // 3.2 关联明细与主表ID，并插入明细
                    foreach (var detail in details)
                    {
                        detail.purchase_id = purchaseId; // 绑定主表ID
                    }
                    int detailRows = await _purchaseOrderRepo.AddPurchaseOrderDetailsAsync(details, transaction);
                    _logger.LogInformation($"进货订单明细插入成功，共{detailRows}条，主表ID：{purchaseId}");

                    // 3.3 提交事务
                    transaction.Commit();
                    return detailRows == details.Count; // 确保所有明细都插入成功
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    _logger.LogError(ex, $"插入进货订单（编号：{order.purchase_order_no}）失败，已回滚事务");
                    throw new Exception($"新增订单失败：{ex.Message}", ex); // 包装异常信息
                }
            }
            catch (ArgumentException ex)
            {
                _logger.LogWarning(ex, "进货订单参数校验失败");
                throw; // 直接抛出参数错误（前端可捕获显示）
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "新增进货订单发生未知错误");
                throw;
            }
        }

        /// <summary>
        /// 分页查询进货订单（含明细汇总数据）
        /// </summary>
        public async Task<PagedViewModel<PurchaseOrderDTO>> GetPurchaseOrdersAsync(
            int currentPage, int pageSize,
            string? purchaseOrderNo, string? status,
            DateTime? startDate, DateTime? endDate)
        {
            try
            {
                _logger.LogInformation($"查询进货订单列表，页码：{currentPage}，每页条数：{pageSize}");
                return await _purchaseOrderRepo.GetPurchaseOrdersAsync(
                    currentPage, pageSize, purchaseOrderNo, status, startDate, endDate);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询进货订单列表失败");
                throw new Exception("获取订单数据失败，请稍后重试", ex);
            }
        }

        #region 私有辅助方法
        /// <summary>
        /// 校验订单和明细的必填参数
        /// </summary>
        private void ValidateOrderAndDetails(PurchaseOrderEntity order, List<WmsOrderDetails> details)
        {
            // 主表校验
            if (string.IsNullOrWhiteSpace(order.purchase_order_no))
                throw new ArgumentException("进货单号不能为空");
            if (order.suppliers_id <= 0)
                throw new ArgumentException("供应商ID无效（必须大于0）");
            if (order.purchase_date == default)
                throw new ArgumentException("进货日期不能为空");
            if (string.IsNullOrWhiteSpace(order.create_by))
                throw new ArgumentException("创建人不能为空");

            // 明细表校验（核心：必须关联货品Product_ID）
            if (details == null || details.Count == 0)
                throw new ArgumentException("至少需要添加一条进货明细");
            for (int i = 0; i < details.Count; i++)
            {
                var detail = details[i];
                if (detail.Product_ID <= 0) // 校验新增的Product_ID字段
                    throw new ArgumentException($"第{i + 1}条明细：货品ID（Product_ID）无效（必须大于0）");
                if (detail.prod_num <= 0)
                    throw new ArgumentException($"第{i + 1}条明细：货品数量必须大于0");
                if (detail.purchase_unit_price <= 0)
                    throw new ArgumentException($"第{i + 1}条明细：进货单价必须大于0");
            }
        }

        /// <summary>
        /// 填充服务端生成的字段（避免前端篡改）
        /// </summary>
        private void FillServerSideFields(PurchaseOrderEntity order, List<WmsOrderDetails> details)
        {
            // 主表字段：服务端统一生成时间（避免客户端时间不一致）
            var now = DateTime.Now;
            order.create_time = now;
            order.update_time = now;
            order.is_delete = "0"; // 默认为未删除

            // 明细表字段：同步主表的创建信息，默认值
            foreach (var detail in details)
            {
                detail.create_by = order.create_by;
                detail.create_time = now;
                detail.update_by = order.create_by;
                detail.update_time = now;
                detail.is_delete = "0"; // 未删除
                detail.purreturn_num = 0; // 初始退货数量为0
                detail.stkIn_num = 0; // 初始入库数量为0
            }
        }
        #endregion

        /// <summary>
        /// 获取订单详情
        /// </summary>
        /// <param name="orderNo"></param>
        /// <returns></returns>
        public async Task<PurchaseOrderDetailAggregateDTO> GetPurchaseOrderDetailAsync(string orderNo)
        {
            var main = await _purchaseOrderRepo.GetMainOrderByNoAsync(orderNo);
            var details = await _purchaseOrderRepo.GetDetailsByNoAsync(orderNo);
            return new PurchaseOrderDetailAggregateDTO
            {
                Main = main,
                Details = details
            };
        }

        public Task UpdateReview(string code, string txt, string status)
        {
            try
            {
                return _purchaseOrderRepo.UpdateReview(code, txt, status);
            }
            catch (Exception ex)
            {
                throw new Exception("网络错误，请重试", ex);
            }
        }

        public async Task BatchUpdateReview(List<string> orderNos, string status, string opinion)
        {
            foreach (var orderNo in orderNos)
            {
                await _purchaseOrderRepo.UpdateReview(orderNo, opinion, status);
            }
        }

        public async Task<PagedViewModel<PurchaseOrderMainDTO>> GetRelatedOrdersAsync(
            string inboundType, List<string> status, int? supplierId, string? orderNo,
            string? purchaser, string? department, string? date, int page, int size)
        {
            if (string.IsNullOrEmpty(inboundType))
                throw new ArgumentException("入库类型不能为空");

            return await _purchaseOrderRepo.GetRelatedOrdersAsync(
                inboundType, status, supplierId, orderNo, purchaser, department, date, page, size);
        }

        public async Task<(PurchaseOrderMainDTO main, List<PurchaseOrderDetailDTO> details)> GetOrderWithDetailsAsync(string orderNo)
        {
            if (string.IsNullOrEmpty(orderNo))
                throw new ArgumentException("进货单号不能为空");

            return await _purchaseOrderRepo.GetOrderWithDetailsAsync(orderNo);
        }

        public async Task<PagedViewModel<PurchaseOrderDetailDTO>> GetOrderGoodsAsync(
            string orderNo, string? codeOrName, string? unit, int page, int size)
        {
            if (string.IsNullOrEmpty(orderNo))
                throw new ArgumentException("进货单号不能为空");

            return await _purchaseOrderRepo.GetOrderGoodsAsync(orderNo, codeOrName, unit, page, size);
        }
    }
}